package co.fitstart.admin.web.controller.trade.order;

import java.math.BigDecimal;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.demo2do.core.BusinessException;
import com.demo2do.core.support.Result;
import com.demo2do.core.utils.JsonUtils;
import com.demo2do.core.web.resolver.Preloading;

import co.fitstart.admin.handler.PaymentHandler;
import co.fitstart.admin.service.OrderService;
import co.fitstart.admin.service.PrincipalService;
import co.fitstart.admin.web.resolver.Secure;
import co.fitstart.entity.finance.OrderInvoiceRecord;
import co.fitstart.entity.order.Order;
import co.fitstart.entity.order.OrderPriceType;
import co.fitstart.entity.order.PaymentMethod;
import co.fitstart.entity.order.RefundMethod;
import co.fitstart.entity.principal.Principal;

/**
 * 
 * @author mohanlan
 *
 */
@Controller
@RequestMapping("/{type}-orders")
public class OrderEditController {
    
    private static final Logger logger = LoggerFactory.getLogger(OrderEditController.class);
    
    @Autowired
    private OrderService orderService;
    
    @Autowired
    private PrincipalService principalService;
    
    @Autowired
    private PaymentHandler paymentHandler;
    
    /**
     * Order profile edit page
     * 
     * @param orderType
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/{orderId}/price", method = RequestMethod.GET)
    public ModelAndView editPrice(@PathVariable("type") String orderType,
                                  @PathVariable("orderId") Long orderId,
                                  @RequestParam("priceType") String priceType){
        
        ModelAndView modelAndView = new ModelAndView("ecommerce/order/view/order-price-edit");
        
        Order order = orderService.loadOrder(orderId);
        
        modelAndView.addObject("order",order);
        modelAndView.addObject("type", orderType);
        modelAndView.addObject("priceType", priceType);
        return modelAndView;
    }
    
    /**
	 * Do edit order profile
	 * 
	 * @param order
	 * @param orderPriceRemarks
	 * @return
	 */
	@RequestMapping(value = "/{orderId}/price", method = RequestMethod.PATCH)
	public @ResponseBody String onEditPrice(@Preloading("orderId") Order order,
	                                        @RequestParam("priceType") String priceType,
	                                        @RequestParam("orderPriceRemarks") String orderPriceRemarks) {
	    
	    Result result = new Result();
	    
	    try {
	        
	        orderService.editOrderPrice(order, OrderPriceType.aliasOf(priceType), orderPriceRemarks);
	        
	        result.success().message("编辑订单成功");
	        
	    } catch (Exception e) {
	        
	        logger.error("editProfile() error: ", e);
	        
	        result.fail().message("编辑订单失败");
	    }
	    
	    return JsonUtils.toJsonString(result);
	}

	/**
     * Display order pay panel
     * 
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/{orderId}/pay", method = RequestMethod.GET)
    public ModelAndView pay(@PathVariable("orderId") Long orderId,
                            @PathVariable("type") String type){
        
        ModelAndView modelAndView = new ModelAndView("ecommerce/order/operations/order-pay");
        
        Order order = orderService.load(Order.class, orderId);
        
        modelAndView.addObject("order",order);
        modelAndView.addObject("type", type);
        
        return modelAndView;
        
    }
    
    /**
     * Do pay order
     * 
     * @param orderId
     * @param paymentMethod
     * @return
     */
    @RequestMapping(value = "/{orderId}/pay", method = RequestMethod.PATCH)
    public @ResponseBody String onPay(@PathVariable("orderId") Long orderId,
                                      PaymentMethod paymentMethod,
                                      @RequestParam(name = "orderNumber", required = false) String orderNumber
                                      /*@RequestParam("paidPrice") BigDecimal paidPrice*/){
        
        Result result = new Result();
        
        try{
            
            Order order = orderService.load(Order.class, orderId);
            
            String orderNo = order.getCode();
            Long customerId = order.getUser().getId();
//            int amount = paidPrice.multiply(new BigDecimal(100)).intValue();
            int amount = order.getPayingPrice();
            String requestNo = "ADMIN_PAY";
            String channel = paymentMethod.toString();
            
            result = paymentHandler.payOrder(order, orderNo, customerId, amount, requestNo, channel, orderNumber);
            logger.info("order [{}], orderNo [{}], customerId [{}], amount [{}], requestNo [{}], channel [{}], orderNumber [{}] ",order, orderNo, customerId, amount, requestNo, channel, orderNumber);
            if(result.isValid()) {
                result.success().message("支付成功");
            } else {
                result.fail().message("手动支付失败");
            }
            
        }catch(Exception e){
            
            result.fail().message("手动支付失败");
            
        }
        
        return JsonUtils.toJsonString(result);
    }
    
    /**
     * Display order close panel
     * 
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/{orderId}/close", method = RequestMethod.GET)
    public ModelAndView close(@PathVariable("orderId") Long orderId){
        
        ModelAndView modelAndView = new ModelAndView("ecommerce/order/operations/order-close");
        
        modelAndView.addObject("orderId",orderId);
        
        return modelAndView;
        
    }

    /**
     * Do close order
     * 
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/{orderId}/close", method = RequestMethod.PATCH)
    public @ResponseBody String onClose(@PathVariable("orderId") Long orderId){
        
        Result result = new Result();
        
        try{
            
            Order order = orderService.load(Order.class, orderId);
            
            if(!order.availableCancel()) {
                throw new BusinessException("该订单不可被关闭");
            }
            
            orderService.close(order);
            
            result.success().message("关闭订单成功");
            
        } catch (BusinessException e) {
            
            result.fail().message(e.getMessage());
            
        } catch(Exception e){
            
            result.fail().message("关闭订单失败");
            
        }
        
        return JsonUtils.toJsonString(result);
        
    }
    

    /**
     * Display edit remarks
     * 
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/{orderId}/remarks", method = RequestMethod.GET)
    public ModelAndView remarks(@PathVariable("orderId") Long orderId){
        
        ModelAndView modelAndView = new ModelAndView("ecommerce/order/operations/order-remarks");
        
        Order order = orderService.load(Order.class, orderId);
        
        modelAndView.addObject("order",order);
        
        return modelAndView;
        
    }
    
    /**
     * Do edit remarks
     * 
     * @param order
     * @return
     */
    @RequestMapping(value = "/{orderId}/remarks", method = RequestMethod.PATCH)
    public @ResponseBody String onRemarks(@Preloading("orderId") Order order){
        
        Result result = new Result();
        
        try{
            
            orderService.editOrder(order);
            
            result.success().message("修改订单备注成功");
            
        }catch(Exception e){
            
            logger.error("onRemarks - ", e);
            
            result.fail().message("修改订单备注失败");
            
        }
        
        return JsonUtils.toJsonString(result);
        
    }
    

    
    /**
     * Display order ship panel
     * 
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/{orderId}/ship", method = RequestMethod.GET)
    public ModelAndView ship(@PathVariable("orderId") Long orderId){
        
        ModelAndView modelAndView = new ModelAndView("ecommerce/order/operations/order-ship");
        
        modelAndView.addObject("orderId",orderId);
        
        return modelAndView;
        
    }
    
    /**
     * Do ship order
     * 
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/{orderId}/ship", method = RequestMethod.PATCH)
    public @ResponseBody String onShip(@PathVariable("orderId") Long orderId,
                                       @RequestParam("expressageCompany") String expressageCompany,
                                       @RequestParam("expressageNumber") String expressageNumber){
        
        Result result = new Result();
        
        try{
            
            Order order = orderService.load(Order.class, orderId);
            
            orderService.ship(order, expressageCompany, expressageNumber);
            
            result.success().message("发货成功");
            
        }catch(Exception e){
            
            logger.error("onShip - ", e);
            
            result.fail().message("发货失败");
            
        }
        
        return JsonUtils.toJsonString(result);
        
    }
    

    /**
     * Display order refund panel
     * 
     * @param orderId
     * @param orderType 
     * @return
     */
    @RequestMapping(value = "/{orderId}/refund", method = RequestMethod.GET)
    public ModelAndView refund(@PathVariable("orderId") Long orderId, @PathVariable("type") String orderType){
        
        ModelAndView modelAndView = new ModelAndView("ecommerce/order/operations/order-refund");
        
        Order order = orderService.get(Order.class, orderId);
        modelAndView.addObject("order", order);
        
        return modelAndView;
    }
    
    /**
     * Do refund order
     * 
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/{orderId}/refund", method = RequestMethod.PATCH)
    public @ResponseBody String onRefund(@PathVariable("orderId") Long orderId,
                                         @RequestParam("refundPrice") BigDecimal refundPrice,
                                         @RequestParam("refundMethod") RefundMethod refundMethod,
                                         @RequestParam("refoundRemarks") String refoundRemarks){
        
        Result result = new Result();
        
        try{
            
            Order order = orderService.load(Order.class, orderId);
            
            if(!order.availableRefund()) {
                throw new BusinessException("该订单不能退款");
            }
            
            orderService.refundOrder(order, refundPrice, refundMethod, refoundRemarks);
            
            result.success().message("订单退款成功");
            
        } catch (BusinessException e) {
            
            result.fail().message(e.getMessage());
            
        } catch(Exception e){
            
            logger.error("onRefund() error: ", e);
            
            result.fail().message("订单退款失败");
            
        }
        
        return JsonUtils.toJsonString(result);
        
    }
    
    /**
     * Display order change salesman panel
     * 
     * @param orderId
     * @param orderType 
     * @return
     */
    @RequestMapping(value = "/{orderId}/change-salesman", method = RequestMethod.GET)
    public ModelAndView changeSalesman(@PathVariable("orderId") Long orderId, @PathVariable("type") String orderType){
        
        ModelAndView modelAndView = new ModelAndView("ecommerce/order/operations/order-change-salesman");
        
        Order order = orderService.get(Order.class, orderId);
        modelAndView.addObject("order", order);
        
        return modelAndView;
    }
    
    /**
     * Do refund order
     * 
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/{orderId}/change-salesman", method = RequestMethod.PATCH)
    public @ResponseBody String onChangeSalesman(@Preloading("orderId") Order order,
                                                 @RequestParam("salesmanId") Long salesmanId){
        
        Result result = new Result();
        
        try{
            
            Principal salesman = principalService.load(Principal.class, salesmanId);
            
            orderService.changeSalesman(order, salesman);
            
            result.success().message("修改销售人员成功");
            
        } catch(Exception e){
            
            logger.error("onChangeSalesman() error: ", e);
            
            result.fail().message("修改销售人员失败");
            
        }
        
        return JsonUtils.toJsonString(result);
        
    }
    
    /**
     * 
     * @param type
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/{orderId}/invoice", method = RequestMethod.GET)
    public ModelAndView invoice(@PathVariable("type") String type, @PathVariable("orderId") Long orderId) {
        
        ModelAndView modelAndView = new ModelAndView("ecommerce/order/operations/order-invoice");
        
        modelAndView.addObject("type", type);
        modelAndView.addObject("orderId", orderId);
        
        return modelAndView;
        
    }
    
    /**
     * 
     * @param operator
     * @param orderId
     * @param orderInvoiceRecord
     * @return
     */
    @RequestMapping(value = "/{orderId}/invoice", method = RequestMethod.PATCH)
    public @ResponseBody String onInvoice(@Secure(property = "id") Long operator,
                                          @PathVariable("orderId") Long orderId,
                                          OrderInvoiceRecord orderInvoiceRecord) {
        
        Result result = new Result();
        
        try {
            
            Order order = orderService.load(Order.class, orderId);
            orderService.invoice(orderInvoiceRecord, order, operator);
            
            result.success().message("开具发票成功");
            
        } catch (Exception e) {
            
            logger.error("onInvoice() error: " , e);
            
            result.fail().message("开具发票失败");
        }
        
        return JsonUtils.toJsonString(result);
        
    }
    
    /**
     * 
     * @param type
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/{orderId}/distribution-channel", method = RequestMethod.GET)
    public ModelAndView editDistributionChannel(@PathVariable("type") String type, @PathVariable("orderId") Long orderId) {
        
        ModelAndView modelAndView = new ModelAndView("ecommerce/order/operations/order-distribution-channel");
        
        Order order = orderService.load(Order.class, orderId);
        
        modelAndView.addObject("type", type);
        modelAndView.addObject("order", order);
        
        return modelAndView;
        
    }
    
    /**
     * 
     * @param order
     * @return
     */
    @RequestMapping(value = "/{orderId}/distribution-channel", method = RequestMethod.PATCH)
    public @ResponseBody String onEditDistributionChannel(@Preloading("orderId") Order order) {
        
        Result result = new Result();
        
        try {
            
            orderService.update(order);
            
            result.success().message("修改销售渠道成功");
            
        } catch (Exception e) {
            
            logger.error("onEditDistributionChannel() error: " , e);
            
            result.fail().message("修改销售渠道失败");
        }
        
        return JsonUtils.toJsonString(result);
        
    }
    
    /**
     * 
     * @param type
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/{orderId}/deposit", method = RequestMethod.GET)
    public ModelAndView deposit(@PathVariable("type") String type, @PathVariable("orderId") Long orderId) {
        
        ModelAndView modelAndView = new ModelAndView("ecommerce/order/operations/order-deposit");
        
        modelAndView.addObject("type", type);
        modelAndView.addObject("orderId", orderId);
        
        return modelAndView;
        
    }
    
    /**
     * 
     * @param orderId
     * @param deposit
     * @param paymentMethod
     * @return
     */
    @RequestMapping(value = "/{orderId}/deposit", method = RequestMethod.PATCH)
    public @ResponseBody String onDeposit(@PathVariable("orderId") Long orderId,
                                          @RequestParam("deposit") BigDecimal deposit,
                                          @RequestParam("paymentMethod") PaymentMethod paymentMethod) {
        
        Result result = new Result();
        
        try {
            
            Order order = orderService.load(Order.class, orderId);
            orderService.deposit(order, deposit, paymentMethod);
            
            result.success().message("支付定金成功");
            
        } catch (Exception e) {
            
            logger.error("onDeposit() error: " , e);
            
            result.fail().message("支付定金失败");
        }
        
        return JsonUtils.toJsonString(result);
        
    }
    
    /**
     * 
     * @param type
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/{orderId}/offer", method = RequestMethod.GET)
    public ModelAndView offer(@PathVariable("type") String type, @PathVariable("orderId") Long orderId) {
        
        ModelAndView modelAndView = new ModelAndView("ecommerce/order/operations/order-offer");
        
        Order order = orderService.load(Order.class, orderId);
        modelAndView.addObject("order", order);
        
        modelAndView.addObject("type", type);
        
        return modelAndView;
        
    }
    
    /**
     * 
     * @param orderId
     * @param offer
     * @param paymentMethod
     * @return
     */
    @RequestMapping(value = "/{orderId}/offer", method = RequestMethod.PATCH)
    public @ResponseBody String onOffer(@PathVariable("orderId") Long orderId,
                                        @RequestParam("offer") BigDecimal offer,
                                        @RequestParam("paymentMethod") PaymentMethod paymentMethod) {
        
        Result result = new Result();
        
        try {
            
            Order order = orderService.load(Order.class, orderId);
            orderService.offer(order, offer, paymentMethod);
            
            result.success().message("支付部分金额成功");
            
        } catch (Exception e) {
            
            logger.error("onOffer() error: " , e);
            
            result.fail().message("支付部分金额失败");
        }
        
        return JsonUtils.toJsonString(result);
        
    }
    
    /**
     * 
     * @param type
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/{orderId}/balance-payment", method = RequestMethod.GET)
    public ModelAndView payBalancePayment(@PathVariable("type") String type, @PathVariable("orderId") Long orderId) {
        
        ModelAndView modelAndView = new ModelAndView("ecommerce/order/operations/order-balance-payment");
        
        Order order = orderService.load(Order.class, orderId);
        
        modelAndView.addObject("type", type);
        modelAndView.addObject("order", order);
        
        return modelAndView;
        
    }
    
    /**
     * 
     * @param orderId
     * @param balance
     * @param paymentMethod
     * @return
     */
    @RequestMapping(value = "/{orderId}/balance-payment", method = RequestMethod.PATCH)
    public @ResponseBody String onPayBalancePayment(@PathVariable("orderId") Long orderId,
                                                    @RequestParam("balance") BigDecimal balance,
                                                    @RequestParam("paymentMethod") PaymentMethod paymentMethod) {
        
        Result result = new Result();
        
        try {
            
            Order order = orderService.load(Order.class, orderId);
            orderService.payBalance(order, balance, paymentMethod);
            
            result.success().message("支付尾款成功");
            
        } catch (Exception e) {
            
            logger.error("onDeposit() error: " , e);
            
            result.fail().message("支付尾款失败");
        }
        
        return JsonUtils.toJsonString(result);
        
    }
    
    /**
     * 
     * @param type
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/{orderId}/edit-user-name", method = RequestMethod.GET)
    public ModelAndView editUserName(@PathVariable("type") String type, @PathVariable("orderId") Long orderId) {
        
        ModelAndView modelAndView = new ModelAndView("ecommerce/order/operations/order-user-name");
        
        Order order = orderService.load(Order.class, orderId);
        modelAndView.addObject("order", order);
        
        modelAndView.addObject("type", type);
        
        return modelAndView;
        
    }
    
    /**
     * 
     * @param orderId
     * @param studentName
     * @return
     */
    @RequestMapping(value = "/{orderId}/edit-user-name", method = RequestMethod.PATCH)
    public @ResponseBody String onEditUserName(@PathVariable("orderId") Long orderId,
                                               @RequestParam("userName") String userName) {
        
        Result result = new Result();
        
        try {
            
            Order order = orderService.load(Order.class, orderId);
            orderService.editUserName(order, userName);
            
            result.success().message("修改用户姓名成功");
            
        } catch (Exception e) {
            
            logger.error("onEditUserName() error: " , e);
            
            result.fail().message("修改用户姓名失败");
        }
        
        return JsonUtils.toJsonString(result);
        
    }
    
    /**
     * 
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/{orderId}/edit-mobile", method = RequestMethod.GET)
    public ModelAndView editMobile(@PathVariable("orderId") Long orderId){
        
        ModelAndView modelAndView = new ModelAndView("ecommerce/order/view/order-mobile-edit");
        
        Order order = orderService.load(Order.class, orderId);
        
        modelAndView.addObject("order",order);
        
        return modelAndView;
        
    }
    
    /**
     * 
     * @param orderId
     * @param mobile
     * @return
     */
    @RequestMapping(value = "/{orderId}/edit-mobile", method = RequestMethod.PATCH)
    public @ResponseBody String onEditMobile(@PathVariable("orderId") Long orderId,
                                             @RequestParam("mobile") String mobile) {
        
        Result result = new Result();
        
        try {
            
            Order order = orderService.load(Order.class, orderId);
            orderService.editMobile(order, mobile);
            
            result.success().message("修改手机号/邮箱成功");
        } catch (BusinessException e) {
            result.fail().message(e.getMessage());
        } catch (Exception e) {
            
            logger.error("onEditMobile() error: " , e);
            
            result.fail().message("修改手机号/邮箱失败");
        }
        
        return JsonUtils.toJsonString(result);
        
    }
}
